package com.flute.icrawler.framework.autoadjust.strategy;

import org.apache.log4j.Logger;

import com.flute.icrawler.framework.autoadjust.FetchAdjuster;
import com.flute.icrawler.framework.autoadjust.IAdjusterStrategy;
import com.flute.icrawler.framework.autoadjust.FetchAdjuster.FetchStatus;

public class DefaultFetchAdjusterStrategy implements IAdjusterStrategy {

	private static Logger logger = Logger
			.getLogger(DefaultFetchAdjusterStrategy.class);

	private FetchAdjuster fetchAdjuster = null;

	private final double TEN_PERCENT_ADD = 1.1;

	private final double TEN_PERCENT_DEL = 0.9;

	private final double FIFTY_PERCENT_ADD = 1.5;

	public DefaultFetchAdjusterStrategy(FetchAdjuster fetchAdjuster) {
		// TODO Auto-generated constructor stub
		this.fetchAdjuster = fetchAdjuster;

	}

	@Override
	public void doAdjust() {
		// TODO Auto-generated method stub

		int successCount = fetchAdjuster
				.getFetchStatusCount(FetchStatus.Success);
		int invalidCount = fetchAdjuster
				.getFetchStatusCount(FetchStatus.Invalid);
		int rejectCount = fetchAdjuster.getFetchStatusCount(FetchStatus.Reject);
		int timeOutCount = fetchAdjuster
				.getFetchStatusCount(FetchStatus.TimeOut);
		int unknowHostExceptionCount = fetchAdjuster
				.getFetchStatusCount(FetchStatus.UnknowHostException);
		int oldInterval = 0;

		oldInterval = fetchAdjuster.getInterval();
		StringBuffer stringBuffer = new StringBuffer();

		stringBuffer.append("successCount" + "=" + successCount + ";");
		stringBuffer.append("invalidCount" + "=" + invalidCount + ";");
		stringBuffer.append("rejectCount" + "=" + rejectCount + ";");
		stringBuffer.append("timeOutCount" + "=" + timeOutCount + ";");
		stringBuffer.append("unknowHostExceptionCount" + "="
				+ unknowHostExceptionCount + ";");

		String countInfo = stringBuffer.toString();

		logger.info(countInfo);
		// if (unknowHostExceptionCount > 5) {
		//
		// int newInterval = oldInterval * 3;
		// if (newInterval <= 0) {
		// logger.warn("newInterval overload set 100:" + newInterval);
		// newInterval = 100;
		// }
		// fetchAdjuster.setInterval(newInterval);
		// logger.warn("unknowHostExceptionCount-change Interval to:"
		// + countInfo + fetchAdjuster.getInterval() + "ms");
		//
		// return;
		// }

		// 没有超时的加快速度
		if (timeOutCount == 0) {
			int newInterval = (int) (oldInterval * TEN_PERCENT_DEL);
			if (newInterval <= 0) {
				logger.warn("newInterval overload set 100:" + newInterval);
				newInterval = 100;
			}
			fetchAdjuster.setInterval(newInterval);
			logger.warn("change Interval to:" + fetchAdjuster.getInterval()
					+ "ms");

			return;
		}

		// 出现拒绝将获取时间间隔增加50%
		if (rejectCount > 0) {
			int newInterval = (int) (oldInterval * FIFTY_PERCENT_ADD);
			if (newInterval <= 0) {
				logger.warn("newInterval overload set 100:" + newInterval);
				newInterval = 100;
			}
			fetchAdjuster.setInterval(newInterval);
			logger.warn("change Interval to:" + countInfo
					+ fetchAdjuster.getInterval() + "ms");

			return;
		}

		// 出现超时并且超时的数量是比成功的一半还多，则加大获取链接时间
		if (timeOutCount > 2 && timeOutCount > (successCount / 2)) {

			double adjustPercent = TEN_PERCENT_ADD;
			if (successCount != 0) {
				adjustPercent = 0.5 + 1.0 * timeOutCount / successCount;
			}

			int newInterval = (int) (oldInterval * adjustPercent);
			if (newInterval <= 0) {
				logger.warn("newInterval overload set 100:" + newInterval);
				newInterval = 100;
			}
			fetchAdjuster.setInterval(newInterval);
			logger.warn("change Interval to:" + countInfo
					+ fetchAdjuster.getInterval() + "ms;" + "adjustPercent="
					+ adjustPercent);

			return;
		}

		// 出现当前抓取的不够多减少百分之10的获取链接时间
		if (successCount >= 0 && successCount < 10) {
			int newInterval = (int) (oldInterval * TEN_PERCENT_DEL);

			if (newInterval <= 0) {
				logger.warn("newInterval overload set 100:" + newInterval);
				newInterval = 100;

			}
			fetchAdjuster.setInterval(newInterval);

			logger.warn("change Interval to:" + countInfo
					+ fetchAdjuster.getInterval() + "ms");

			return;
		}

		if (rejectCount == 0) {
			int newInterval = oldInterval / 2;
			if (newInterval <= 0) {
				logger.warn("newInterval overload set 100:" + newInterval);
				newInterval = 100;
			}
			fetchAdjuster.setInterval(newInterval);
			logger.warn("change Interval to:" + countInfo
					+ fetchAdjuster.getInterval() + "ms");

			return;
		}

	}

	@Override
	public void afterAdjust() {
		// TODO Auto-generated method stub
		fetchAdjuster.clearFetchStatusCount();
	}
}
